package principal;


import java.awt.geom.Point2D;
import java.util.Iterator;
import java.util.LinkedList;


public class FabricaFormaPrincipal implements IFabrica {

	public LinkedList<Calle> calles;
	public LinkedList<Forma> formas;
	public LinkedList<Linea> lineas;
	private Trazo t = null;
	
	public FabricaFormaPrincipal(LinkedList<Calle> calles,LinkedList<Forma> formas, LinkedList<Linea> lineas){
		this.calles = calles;
		this.formas = formas;
		this.lineas = lineas;
	}	
	
	@Override
	public void fabricaForma(int a) {
		if(a>=1 && a<=4)
			fabricaFormaPrincipal(a);
		if(a == 5)
			fabricaLinea();
		if(a == 6)
			fabricaCalle();
		
	}

	private void fabricaCalle() {
		System.out.println("llego");
		calles.add(new Calle(t.get_punto_mas_alto(),t.get_punto_mas_bajo()));
		
	}

	private void fabricaLinea() {
		Forma or = null;
    	Forma dest = null;
    	
    	or = esta_en_una_forma(t.getOrigen());
    	dest = esta_en_una_forma(t.getFin());
    	
    	if(or!=null && dest != null && or!=dest){//los dos extremos son formas
    		if(or.getCalle()==dest.getCalle())
    			lineas.add(new Linea(or, dest, 1));
    		else
    			lineas.add(new Linea(or, dest, 2));
    	}
    	if(or==null && dest!=null && dest.getTipo()==2 ||
    			dest==null && or!=null && or.getTipo()==2){//Solo tiene un extremo, que es un documento
    		Point2D p;
    		Forma f;
    		if(or == null){
    			p = t.getOrigen();
    			f = dest;
    		}
    		else{
    			p = t.getFin();
    			f = or;
    		}
    		
    		//Itero sobre las lineas a ver si hay una que este cerca del extremo del trazo pintado
    		Iterator<Linea> it = lineas.iterator();
    		Linea l_tmp;
    		Recta r_tmp;
    		boolean enc = false;
    		while(it.hasNext() && !enc){
    			l_tmp = (Linea)it.next();
    			r_tmp = new Recta(l_tmp);
    			if(r_tmp.distancia(p)<10){
    				enc = true;
    				lineas.add(new Linea(f, r_tmp));
    			}
    		}
    	}
		
	}

	private void fabricaFormaPrincipal(int a) {
		Point2D origen = t.getInicioDibujo();
		Calle calleForma= getCalle();
		
		Forma f = new Forma((int)origen.getX(),(int)origen.getY(),a, calleForma);
		formas.add(f);
		
	}

	@Override
	public void setTrazo(Trazo t) {
		this.t = t;
		
	}
	
	private Calle getCalle() {
		Iterator<Calle> it = calles.iterator();
		Calle tmp, ret = null;
		boolean enc = false;
		while(it.hasNext() && !enc){
			tmp = (Calle)it.next();
			if(tmp.contieneTrazo(t)){
				enc = true;
				ret = tmp;
			}
		}

		return ret;
	}

	private Forma esta_en_una_forma(Point2D origen) {
		Iterator<Forma> it = formas.iterator();
		Forma tmp = null;
		Forma ret = null;
		boolean enc = false;
		while(it.hasNext() && !enc){
			tmp = (Forma)it.next();
			if(tmp.getTipo()==1){
				if(origen.getX()-tmp.getPos().getX()<160 && origen.getY()-tmp.getPos().getY()<60 && 
						origen.getX()-tmp.getPos().getX()>0 && origen.getY()-tmp.getPos().getY()>0){
					enc = true;
					ret = tmp;
				}
			}
			if(tmp.getTipo()==2){
				if(origen.getX()-tmp.getPos().getX()<33 && origen.getY()-tmp.getPos().getY()<50&& 
						origen.getX()-tmp.getPos().getX()>0 && origen.getY()-tmp.getPos().getY()>0){
					enc = true;
					ret = tmp;
				}
			}
			
			if(tmp.getTipo()==7 || tmp.getTipo()==8 || tmp.getTipo()==5 || tmp.getTipo()==6 || tmp.getTipo()==9 || tmp.getTipo()==10){
				if(origen.getX()-tmp.getPos().getX()<40 && origen.getY()-tmp.getPos().getY()<40&& 
						origen.getX()-tmp.getPos().getX()>0 && origen.getY()-tmp.getPos().getY()>0){
					enc = true;
					ret = tmp;
				}
			}
		}
		return ret;
	}


}
